package toy.keli.picmap.tools;

import android.content.Context;
import android.util.Log;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeOption;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;

import java.util.concurrent.CountDownLatch;

import toy.keli.picmap.util.utilCallback;

public class Location {
    public Context bmapAct;
    public callback func;
    public Location(Context context) {
        bmapAct=context;
    }

    //定位部分  https://zhuanlan.zhihu.com/p/41290348
    public BDLocation mLocation;

    public static void getStatusInfo(MapStatus mapStatus, utilCallback.geoGet func) {
        double x=(mapStatus.bound.northeast.longitude+mapStatus.bound.southwest.longitude)/2,
               y=(mapStatus.bound.northeast.latitude+mapStatus.bound.southwest.latitude)/2;
        LatLng point = new LatLng(y, x);
        GeoCoder mCoder = GeoCoder.newInstance();
        mCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
            @Override
            public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {}

            @Override
            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
                func.call(reverseGeoCodeResult);
            }
        });
        mCoder.reverseGeoCode(new ReverseGeoCodeOption()
                .location(point)
                // 设置是否返回新数据 默认值0不返回，1返回
                .newVersion(1)
                // POI召回半径，允许设置区间为0-1000米，超过1000米按1000米召回。默认值为1000
                .radius(500));

    }

    public class LocationListener extends BDAbstractLocationListener {
        public MapView mMapView;

        @Override
        public void onReceiveLocation(BDLocation location) {
            //mapView 销毁后不在处理新接收的位置
            if (location == null || mMapView == null){
                return;
            }
            BaiduMap mBaiduMap=mMapView.getMap();

            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(location.getDirection()).latitude(location.getLatitude())
                    .longitude(location.getLongitude()).build();
            mBaiduMap.setMyLocationData(locData);
            mLocation=location;
            Log.d("kdebug", String.valueOf(location));

            if(func!=null && location!=null) {
                func.call(location);
                func=null;
            }
        }
    }

    public void addToolsLocation(MapView mMapView,callback func){
        this.func=func;
        //定位初始化
        LocationClient mLocationClient = new LocationClient(bmapAct);

        //通过LocationClientOption设置LocationClient相关参数
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setIsNeedAddress(true);//就是这个方法设置为true，才能获取当前的位置信息
//        option.setScanSpan(10000);

        //设置locationClientOption
        mLocationClient.setLocOption(option);

        //注册LocationListener监听器
        LocationListener myLocationListener = new LocationListener();
        myLocationListener.mMapView=mMapView;
        mLocationClient.registerLocationListener(myLocationListener);
        //开启地图定位图层
        mLocationClient.start();
    }

    public static interface callback{
        public void call(BDLocation location);
    }

    public static interface callbackaddr{
        public void call(Object sum);
    }
    public static interface callback2addr{
        public void call(String sum);
    }
    public static interface callback2point{
        public void call(LatLng sum);
    }

    public static void PointToAddr(LatLng p, callback2addr func){
        getAddr(p,(rt)->{func.call(String.valueOf(rt)); });
        //return (String)new NetRequest(p).data();
    }
    public static void AddrToPoint(String addr, callback2point func){
        getAddr(addr,(rt)->{func.call((LatLng)rt); });
    }
    //Android中异步转同步（主线程等待子线程）方法总结  https://blog.csdn.net/u011082160/article/details/99441697
    static class NetRequest implements Runnable{
        private Object params;
        private Object request;
        CountDownLatch countDownLatch;
        public Object data(){
            return request;
        }
        NetRequest(Object params){
            this.params=params;
            countDownLatch = new CountDownLatch(1);
            Thread thread = new Thread(this);
            thread.start();
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void run() {
            getAddr(params,(Object p)->{
                request=p;
                countDownLatch.countDown();//计数减1
            });
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            countDownLatch.countDown();//计数减1
        }
    }
    //坐标转地址  https://lbsyun.baidu.com/index.php?title=androidsdk/guide/search/geo
    public static void getAddr(Object params, callbackaddr func){
        GeoCoder mCoder = GeoCoder.newInstance();
        mCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
            @Override
            public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
                if (null != geoCodeResult && null != geoCodeResult.getLocation()) {
                    if (geoCodeResult == null || geoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
                        //没有检索到结果
                        func.call(null);
                        return;
                    } else {
                        double latitude = geoCodeResult.getLocation().latitude;
                        double longitude = geoCodeResult.getLocation().longitude;
                        LatLng point=new LatLng(latitude,longitude);
                        func.call(point);
                    }
                }
            }

            @Override
            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
                if (reverseGeoCodeResult == null || reverseGeoCodeResult.error != SearchResult.ERRORNO.NO_ERROR) {
                    //没有找到检索结果
                    func.call(null);
                    return;
                } else {
                    //详细地址
                    String address = reverseGeoCodeResult.getAddress();
                    //行政区号
                    int adCode = reverseGeoCodeResult. getCityCode();
                    func.call(address);
                }
                mCoder.destroy();
            }
        });

        if(params instanceof  LatLng) {
            LatLng point = (LatLng) params;
            mCoder.reverseGeoCode(new ReverseGeoCodeOption()
                    .location(point)
                    // 设置是否返回新数据 默认值0不返回，1返回
                    .newVersion(1)
                    // POI召回半径，允许设置区间为0-1000米，超过1000米按1000米召回。默认值为1000
                    .radius(500));
        }else {
            String name = (String) params;
            String[] addr = name.split(" ");
            mCoder.geocode(new GeoCodeOption()
                    .city(addr[0])
                    .address(addr.length==1 ? addr[0] : addr[1]));
        }
    }



}
